package com.hxzy.controller.admin;

import com.hxzy.common.consts.RedisConst;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.vo.R;
import com.hxzy.dto.system.AdminLoginDTO;
import com.hxzy.service.system.SysMenuService;
import com.hxzy.service.system.SysRoleService;
import com.hxzy.service.system.SysUserService;
import com.hxzy.service.system.impl.TokenService;
import com.hxzy.util.AdminInfoUtil;
import com.hxzy.vo.AdminLoginVO;
import com.hxzy.vo.SysMenuVO;
import com.hxzy.vo.router.RouterVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Api(tags = "后台用户/商家登录API")
@RestController
@RequestMapping(value = "/api")
public class AdminLoginController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private TokenService tokenService;

    /**
     * 获取用户的权限方式，如果true代表实时获取（数据库）,否则获取redis缓存权限
     */
    @Value(value = "${userinfo.permission:false}")
    private boolean userPermisson;


    @ApiOperation(value = "登录")
    @PostMapping(value = "/login")
    public R login(@RequestBody @Valid AdminLoginDTO adminLoginDTO){
        //验证验证码是否过期
        String redisKey= RedisConst.getRedisKey(RedisConst.CAPTCHA_KEY,adminLoginDTO.getUuid());
        //查询键是不是存在
        Object redisValue=this.redisTemplate.opsForValue().get(redisKey);

        if(redisValue==null){
            return R.build(AckCode.SMS_CODE_OVERTIME);
        }
        //再判断值是否相等
        if(!redisValue.toString().equalsIgnoreCase(adminLoginDTO.getCode())){
            return R.build(AckCode.SMS_CODE_WRONG);
        }
        //验证码验证成功，删除验证码
        this.redisTemplate.delete(redisKey);

        //用户登录
        AdminLoginVO adminLoginVO = this.sysUserService.login(adminLoginDTO);

        //换令牌
        String jwtToken = this.tokenService.createJwtToken(adminLoginVO);

        //之前这个用户让它失效
        Object hashRedisValue = this.redisTemplate.opsForHash().get(RedisConst.ADMIN_LOGIN_ALL, adminLoginVO.getSysUser().getUserId()+"");
        //该账户有登录过
        if(hashRedisValue!=null){
           String uuidValue=hashRedisValue.toString();
           String stringRedisKey=RedisConst.getRedisKey(RedisConst.ADMIN_LOGIN_KEY,uuidValue);
           //删除之前的登录uuid
           this.redisTemplate.delete(stringRedisKey);
        }
        //写入本次的登录uuid
        this.redisTemplate.opsForHash().put(RedisConst.ADMIN_LOGIN_ALL, adminLoginVO.getSysUser().getUserId()+"", adminLoginVO.getUuid());

        return R.okHasData(jwtToken);
    }


    @ApiOperation(value = "得到当前用户信息")
    @GetMapping(value = "/user/info")
    public R userInfo(){

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
       AdminLoginVO  adminLoginVO= (AdminLoginVO) authentication.getPrincipal();

        Map<String,Object> data=new HashMap<>();

        data.put("user", adminLoginVO.getSysUser());
        data.put("isSuperMan",adminLoginVO.isSuperMan());

        if(this.userPermisson){
            //如果想要实时的权限,查询数据库
            Set<String> roleSet = this.sysRoleService.searchUserOwnRole(adminLoginVO.getSysUser().getUserId());
            Set<String> permSet=this.sysMenuService.searchUserOwnPerm(adminLoginVO.getSysUser().getUserId());
            data.put("roles", roleSet);
            data.put("permissions", permSet);
        }else{
            //如果取得登录的时候缓存权限
            data.put("roles", adminLoginVO.getRoleSet());
            data.put("permissions", adminLoginVO.getPermsSet());
        }

        return R.okHasData(data);
    }

    @ApiOperation(value = "获取当前用户的动态路由信息")
    @GetMapping("/getRouters")
    public R getRouters() {
        Long userId = AdminInfoUtil.getUserId();
        // 拉取一级菜单
        List<SysMenuVO> menus = sysMenuService.selectMenuTreeByUserId(userId);
        // 返回的是RouterVo列表
        List<RouterVO> routerVOS = sysMenuService.buildMenuRouter(menus);
        return R.okHasData(routerVOS);
    }

}
